home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2000 #1
/
Amiga Plus CD - 2000 - No. 1.iso
/
Tools
/
Dev
/
mamesrc
/
fixsrc
/
scandir.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-12-03
|
4KB
|
238 lines
#include <stdio.h>
#include <stdlib.h>
#include <dos/dos.h>
#include <inline/dos.h>
#include "scandir.h"
extern struct DosLibrary *DOSBase;
struct dir
{
struct dir *Next;
struct dir *Prev;
struct FileInfoBlock *FIB;
BPTR Lock;
int NameLen;
};
typedef struct dir dir_t;
int ScanDir(char *dir, dir_f func, int flags, char *pattern)
{
STRPTR parsed_pattern;
dir_t root_dir;
dir_t *current_dir;
char name[256];
int name_len;
int len;
int rc;
root_dir.Next = NULL;
root_dir.Prev = NULL;
root_dir.FIB = NULL;
current_dir = &root_dir;
if(pattern)
{
len = strlen(pattern);
if(!(parsed_pattern = malloc(2*len+2)))
return(SDE_OutOfMemory);
if(ParsePatternNoCase(pattern, parsed_pattern, 2*len+2) < 0)
return(SDE_PatternError);
}
else
parsed_pattern = NULL;
if(dir)
{
name_len = strlen(dir);
if(name_len >= sizeof(name))
return(SDE_NameBufferFull);
strcpy(name, dir);
if((name[name_len-1] != ':') || (name[name_len-1] != '/'))
{
if(name_len >= sizeof(name) - 1)
return(SDE_NameBufferFull);
name[name_len] = '/';
name_len++;
name[name_len] = 0;
}
}
else
{
name_len = 0;
name[0] = 0;
}
rc = SDE_LockFailed;
while((current_dir->Lock = Lock(name, ACCESS_READ)))
{
if(!current_dir->FIB)
{
if(!(current_dir->FIB = AllocDosObject(DOS_FIB, NULL)))
{
rc = SDE_AllocFIBFailed;
break;
}
}
if(!Examine(current_dir->Lock, current_dir->FIB))
{
rc = SDE_ExamineFailed;
break;
}
if(current_dir->FIB->fib_DirEntryType <= 0)
{
rc = SDE_LockNotDir;
break;
}
while(1)
{
if(ExNext(current_dir->Lock, current_dir->FIB))
{
if(current_dir->FIB->fib_DirEntryType > 0)
{
if(!(flags & SDF_DirPattern)
|| MatchPatternNoCase(parsed_pattern, current_dir->FIB->fib_FileName))
{
len = strlen(current_dir->FIB->fib_FileName);
if(name_len + len >= sizeof(name))
{
rc = SDE_NameBufferFull;
break;
}
strcpy(&name[name_len], current_dir->FIB->fib_FileName);
if(flags & SDF_DirCall)
{
if(!func(name, current_dir->FIB))
{
rc = SDE_FuncBreak;
break;
}
}
if(flags & SDF_Recursive)
{
if(name_len + len >= sizeof(name) - 1)
{
rc = SDE_NameBufferFull;
break;
}
current_dir->NameLen = name_len;
if(current_dir->Next)
current_dir = current_dir->Next;
else
{
if(!(current_dir->Next = calloc(sizeof(dir_t),1)))
{
rc = SDE_OutOfMemory;
break;
}
current_dir->Next->Prev = current_dir;
current_dir = current_dir->Next;
}
name_len += len;
name[name_len] = '/';
name_len++;
name[name_len] = 0;
break;
}
}
}
else if(current_dir->FIB->fib_DirEntryType < 0)
{
if((flags & SDF_FileCall) && (!(flags & SDF_FilePattern)
|| MatchPatternNoCase(parsed_pattern, current_dir->FIB->fib_FileName)))
{
len = strlen(current_dir->FIB->fib_FileName);
if(name_len + len >= sizeof(name))
{
rc = SDE_NameBufferFull;
break;
}
strcpy(&name[name_len], current_dir->FIB->fib_FileName);
if(!func(name, current_dir->FIB))
{
rc = SDE_FuncBreak;
break;
}
}
}
}
else
{
if(current_dir->Lock)
{
UnLock(current_dir->Lock);
current_dir->Lock = NULL;
}
if(current_dir->Prev)
{
current_dir = current_dir->Prev;
name_len = current_dir->NameLen;
}
else
{
rc = SDE_OK;
break;
}
}
}
if(rc != SDE_LockFailed)
break;
}
current_dir = &root_dir;
while(1)
{
if(current_dir->FIB)
FreeDosObject(DOS_FIB, current_dir->FIB);
if(current_dir->Lock)
UnLock(current_dir->Lock);
if(current_dir->Next)
current_dir = current_dir->Next;
else
break;
}
while(current_dir->Prev)
{
current_dir = current_dir->Prev;
free(current_dir->Next);
}
if(parsed_pattern)
free(parsed_pattern);
return(rc);
}